const sequelize = require("../config/database");
const Category = require("./category");
const Order = require("./order");
const OrderItem = require("./orderItem");
const Product = require("./product");
const User = require("./user");

/**
 * 第4点：模型关联配置函数
 * 定义所有模型之间的关联关系（1对多/多对1）
 * 核心作用：让Sequelize识别模型间依赖，支持联表查询（如Order关联User、OrderItem关联Product）
 */
const initAssociations = () => {
  // 1. User ↔ Order：1对多（一个用户可创建多个订单，一个订单归属一个用户）
  User.hasMany(Order, {
    foreignKey: "userId", // 外键：Order表中的userId字段
    as: "orders", // 别名：从User查Order时用的名称（如user.getOrders()）
    onDelete: "RESTRICT", // 限制：删除用户时，若有未处理订单则禁止删除（避免数据孤儿）
    onUpdate: "CASCADE", // 级联：用户ID更新时，关联的订单userId同步更新
  });
  Order.belongsTo(User, {
    foreignKey: "userId", // 外键：与User.hasMany对应
    as: "user", // 别名：从Order查User时用的名称（如order.getUser()，联表查询时用include: { model: User, as: 'user' }）
  });

  // 2. Order ↔ OrderItem：1对多（一个订单包含多个订单项，一个订单项归属一个订单）
  Order.hasMany(OrderItem, {
    foreignKey: "orderId", // 外键：OrderItem表中的orderId字段
    as: "orderItems", // 别名：从Order查OrderItem时用（如order.getOrderItems()）
    onDelete: "CASCADE", // 级联：删除订单时，关联的订单项同步删除（避免孤儿数据）
    onUpdate: "CASCADE",
  });
  OrderItem.belongsTo(Order, {
    foreignKey: "orderId",
    as: "order", // 别名：从OrderItem查Order时用
  });

  // 3. Product ↔ OrderItem：1对多（一个产品可出现在多个订单项，一个订单项对应一个产品）
  Product.hasMany(OrderItem, {
    foreignKey: "productId", // 外键：OrderItem表中的productId字段
    as: "orderItems", // 别名：从Product查OrderItem时用
    onDelete: "RESTRICT", // 限制：删除产品时，若有未完成订单的订单项则禁止删除
    onUpdate: "CASCADE",
  });
  OrderItem.belongsTo(Product, {
    foreignKey: "productId",
    as: "product", // 别名：从OrderItem查Product时用（联表查询核心，如include: { model: Product, as: 'product' }）
  });

  // 4. Category ↔ Product：1对多（一个分类包含多个产品，一个产品归属一个分类）
  // （补充分类与产品的关联，之前的接口中Product有categoryId，需完善关联）
  Category.hasMany(Product, {
    foreignKey: "categoryId",
    as: "products",
    onDelete: "RESTRICT",
    onUpdate: "CASCADE",
  });
  Product.belongsTo(Category, {
    foreignKey: "categoryId",
    as: "category",
  });

  console.log("[数据库成功] 所有模型关联配置完成");
};

/**
 * 初始化数据库连接并验证
 * 功能：
 * 1. 验证数据库连接是否有效
 * 2. 可选同步模型结构到数据库（默认注释，生产环境谨慎启用）
 * 3. 处理连接错误，生产环境下连接失败自动退出进程
 */
const initDatabase = async () => {
  try {
    // 验证数据库连接配置是否正确
    await sequelize.authenticate();
    console.log("[数据库成功] 已连接到 MySQL 数据库");
    initAssociations();

    // 模型同步开关（默认关闭，根据环境需求手动启用）
    // alter: true 会尝试修改表结构以匹配模型定义（不删除数据）
    // force: true 会删除现有表并重新创建（谨慎使用，会丢失数据）
    // await sequelize.sync({ alter: true });
    // console.log("[数据库成功] 所有模型已同步");
  } catch (error) {
    // 连接失败时输出错误信息
    console.error("[数据库失败] 连接或同步失败：", error.message);

    // 生产环境下数据库连接失败时，终止应用进程
    if (process.env.NODE_ENV === "production") {
      console.error("[系统退出] 生产环境数据库连接失败，无法继续运行");
      process.exit(1); // 非0状态码表示异常退出
    }
  }
};

// 导出数据库核心对象
module.exports = {
  sequelize, // Sequelize实例，用于直接操作数据库
  initDatabase, // 数据库初始化函数
  // 导出所有模型（供控制器/服务层调用，如 User.create()、Order.findAll()）
  Category,
  Order,
  OrderItem,
  Product,
  User,
};
